﻿using Microsoft.AspNetCore.Authorization;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
using System.Linq.Dynamic.Core;
using Wuther.Infrastructure.Utils;
using System.Text.Json.Serialization;
using System.Text.Json;
using Wuther.Infrastructure.Dtos;
namespace Wuther.Infrastructure.Organizations
{
    /// <summary>
    /// 部门信息接口实现
    /// </summary>
    public class OrganizationAppService : CrudAppService<
         Organization,
         OrganizationDto,
         Guid,
         GetOrganizationInput,
         CreateOrUpdateOrganizationDto,
         CreateOrUpdateOrganizationDto>, IOrganizationAppService
    {
        public OrganizationAppService(IRepository<Organization, Guid> repository)
            : base(repository)
        {
        }

          #region 设置查询条件
        /// <summary>
        /// 设置查询条件
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>

        protected async override Task<IQueryable<Organization>> CreateFilteredQueryAsync(GetOrganizationInput input)
        {

            return await Repository.GetQueryableAsync();
        }
        #endregion



        /// <summary>
        /// 获取列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async override Task<PagedResultDto<OrganizationDto>> GetListAsync(GetOrganizationInput input)
        {
            var query = await CreateFilteredQueryAsync(input);
            var totalCount = await query.CountAsync();
            var list = query.AsNoTracking().OrderByDescending(x=>x.CreationTime).PageBy(input.SkipCount, input.MaxResultCount).ToList();
            return new PagedResultDto<OrganizationDto>()
            {
                TotalCount = totalCount,
                Items = ObjectMapper.Map<List<Organization>, List<OrganizationDto>>(list)
            };
        }
         /// <summary>
        /// 获取列表（不分页）
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>

        public async Task <List<OrganizationDto>> GetAllListAsync(GetOrganizationInput input)
        {
            var query = await CreateFilteredQueryAsync(input);
            var totalCount = await query.CountAsync();
            var list = query.AsNoTracking().OrderByDescending(x=>x.CreationTime).ToList();
            return  ObjectMapper.Map<List<Organization>, List<OrganizationDto>>(list);
        }


        /// <summary>
        /// 获取部门树
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<List<DeptTreeDto>> GetTreeListAsync(GetOrganizationInput input)
        {
            var query = await CreateFilteredQueryAsync(input);
            var totalCount = await query.CountAsync();
            var list = query.AsNoTracking().OrderByDescending(x => x.CreationTime).ToList();
            var deptList = list.Select(c => new DeptTreeDto()
            {
                id = c.Id,
                parentId = c.ParentId,
                name = c.DisplayName,
                orderNo = c.AreaCode,
            }).ToList();
            
            var treeList = GenerateTree(deptList,c=>c.id,c=>c.parentId);


            return treeList.ToList();
        }

        private IEnumerable<DeptTreeDto> GenerateTree(
           IEnumerable<DeptTreeDto> collection,
           Func<DeptTreeDto,Guid?> idSelector,
           Func<DeptTreeDto, Guid?> parentIdSelector,
           Guid? rootId = default(Guid?))
        {
            var list = collection.Where(u =>
            {
                var selector = parentIdSelector(u);
                return (rootId == null && selector == null)
                       || (rootId != null && rootId.Equals(selector));
            });
            foreach (var c in list)
            {
                yield return new DeptTreeDto
                {
                    id = c.id,
                    parentId = c.parentId,
                    name = c.name,
                    orderNo = c.orderNo,
                    children = GenerateTree(collection,idSelector, parentIdSelector, idSelector(c)).ToList(),
                };
            }
        }
    }
}
